﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.ServiceLocation;
using Pap.Core.Utilities;
using Pap.Data;
using Pap.Data.Abstraction.Utils;
using Pap.Services;
using Pap.Services.WorkflowEngine;
using Pap.Web.Utils;

namespace Pap.Web.Modules.Loan.ViewModel
{
    /// <summary>
    /// 
    /// </summary>
    public class ResponsibleSocialFeasibilityWaitingListViewModel : IViewModel
    {
        /// <summary>
        /// 
        /// </summary>
        ILoanRepository _LoanRepository;
        /// <summary>
        /// 
        /// </summary>
        IWorkflowService _WfService;
        /// <summary>
        /// 
        /// </summary>
        IAdministrationRepository _AdministrationRepository;

        /// <summary>
        /// Initializes a new instance of the <see cref="ResponsibleSocialFeasibilityWaitingListViewModel"/> class.
        /// </summary>
        /// <param name="loanRepo">The loan repo.</param>
        /// <param name="wf">The wf.</param>
        /// <param name="adminRepository">The admin repository.</param>
        public ResponsibleSocialFeasibilityWaitingListViewModel(ILoanRepository loanRepo, IWorkflowService wf, IAdministrationRepository adminRepository)
        {
            this._LoanRepository = loanRepo;
            this._WfService = wf;
            this._AdministrationRepository = adminRepository;
        }

        /// <summary>
        /// Gets the available decisions.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ActionTypes> GetAvailableDecisions()
        {
            return _WfService.GetAvailableActionsByStep(Steps.ResearchAndStudy);
        }

        /// <summary>
        /// Gets the loans for current responsible.
        /// </summary>
        /// <param name="committeeID">The committee ID.</param>
        /// <param name="responsibleID">The responsible ID.</param>
        /// <returns></returns>
        public IEnumerable GetLoansForCurrentResponsible(Guid committeeID,
            Guid responsibleID)
        {
            var thisStepLoans = _LoanRepository.FindCustomerLoans(Loan => (_WfService.GetInStep(Steps.ResearchAndStudy)).Contains(Loan.LoanID));
            IEnumerable<IProject> userProjects = _AdministrationRepository.GetUserProjects(responsibleID);
            var results = thisStepLoans.Where(l => l.CommitteeID == committeeID && l.ResponsibleID == responsibleID && userProjects.Contains(l.ProjectStage.ProjectObj));

            var loans = from loan in results
                        orderby loan.LoanNumber ascending
                        select new
            {
                CustomerName = _LoanRepository.GetCustomerByID(loan.CustomerID).CustomerName,
                LoanCreatedDate = loan.LoanCreatedDate,
                LoanID = loan.LoanID,
                LoanNumber = loan.LoanNumber,
                LoanAmount = loan.LoanAmount,
                PaymentMethod = loan.LoanPaymentMethodObj.LoanPaymentMethodName,
                LoanName = loan.LoanName,
                LoanStatus = _WfService.GetStep(_WfService.GetProcessInstanceIDByEntity(loan.LoanID)).DisplayName.ToString(),
                Validated = loan.FeasibilityStudyObj != null && loan.SocialResarchObj != null,
                PreviousNotes = _WfService.GetStep(_WfService.GetProcessInstanceIDByEntity(loan.LoanID)).PreviousNotes,
                Researched = loan.SocialResarchObj != null,
                FeasibilityStudied = loan.FeasibilityStudyObj != null
            };

            return loans;
        }

        /// <summary>
        /// Takes the decision.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        /// <param name="action">The action.</param>
        public void TakeDecision(Guid loanID, Pap.Services.WorkflowEngine.ActionTypes action)
        {
            using (IUnitOfWork transaction = ServiceLocator.Current.GetInstance<IUnitOfWork>())
            {
                Guid processInstanceID = _WfService.GetProcessInstanceIDByEntity(loanID);
                _WfService.Move(action, processInstanceID, RegistryInfo.UserID, "", null);

                transaction.Commit();
            }
        }

        /// <summary>
        /// Takes the loan decisions.
        /// </summary>
        /// <param name="LoansIDs">The loans I ds.</param>
        /// <param name="LoanDecisions">The loan decisions.</param>
        /// <param name="Notes">The notes.</param>
        /// <param name="FreezedDates">The freezed dates.</param>
        public void TakeLoanDecisions(List<Guid> LoansIDs, List<ActionTypes> LoanDecisions, List<string> Notes, List<DateTime?> FreezedDates)
        {
            using (IUnitOfWork trancaction = ServiceLocator.Current.GetInstance<IUnitOfWork>())
            {
                for (int i = 0; i < LoanDecisions.Count; i++)
                {
                    ICustomerLoan loan = _LoanRepository.GetCustomerLoanByID(LoansIDs[i]);
                    if (LoanDecisions[i] == ActionTypes.Submit || LoanDecisions[i].Equals(ActionTypes.Refuse))
                    {
                        if (loan.SocialResarchObj == null || loan.FeasibilityStudyObj == null)
                            continue;
                    }
                    Guid processInstanceID = _WfService.GetProcessInstanceIDByEntity(LoansIDs[i]);
                    _WfService.Move(LoanDecisions[i], processInstanceID, RegistryInfo.UserID, Notes[i], FreezedDates[i]);
                }

                trancaction.Commit();
            }
        }
    }
}
